package com.example.bbbb.tansaction;


import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2023-12-12
 * Time: 20:11
 */

@RestController
public class Test {

    /**
     * 事务的属性:
     * 1.★propagation:用来设置事务的传播行为
     *      事务的传播行为:一个方法运行在了一个开启了事务的方法中时，当前方法是使用原来的事务还是开启一个新的事务
     *      -Propagation.REQUIRED:默认值，使用原来的事务
     *      -Propagation.REQUIRES_NEW。将原来的事务挂起，开启一个新的事务
     * 2.isolation:用来设置事务的隔离级别
     *      -Isolation.REPEATABLE_READ:可重复读，MySQL默认的隔离级别
     *      -Isolation.READ_COMMITTED:读已提交,Oracle默认的隔离级别，开发时通常使用的隔离级别
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.MANDATORY)
    public void test() {
    }



    /**
     * Executors 内部也是对 ThreadPoolExecutors 的封装
     * 所以会产生 OOM 的问题，阿里开发手册更推荐后者
     *
     */
    public void test1() {


        // 都没有设置拒绝策略，使用默认的 AbortPolicy
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                0,
                Integer.MAX_VALUE,
                60L,
                TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>()
        );
        // 内部实现如上
        // SynchronizedQueue 一个不存储元素的阻塞队列，每个插入操作必须等到另一个线程调用移除操作，否则插入操作一直处于阻塞状态
        // 因为 SynchronizedQueue 没有容量，而且maximumPoolSize（最大线程数）为Integer.MAX_VALUE
        // 所以如果任务很多会不断地创建非核心线程，导致 OOM（内存溢出）
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

        ThreadPoolExecutor executor1 = new ThreadPoolExecutor(
                5,
                5,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>()
        );
        // LinkedBlockingQueue 不指定容量，默认是 Integer.MAX_VALUE
        // 核心线程过少，任务会不断地添加到该阻塞队列，最终导致 OOM
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);

        ThreadPoolExecutor executor2 = new ThreadPoolExecutor(
                1,
                1,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>()
        );
        // 同理 Executors.newFixedThreadPool(1)
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();



        ThreadPoolExecutor executor3 = new ThreadPoolExecutor(
                1,
                1,
                0,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(),
                new ThreadPoolExecutor.AbortPolicy()// 默认的拒绝策略
        );

        // 内部提供的四大拒绝策略

        // 任务队列满后续的直接抛弃
        // 并抛出异常RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
        new ThreadPoolExecutor.AbortPolicy();

        new ThreadPoolExecutor.DiscardPolicy();// 任务队列满后续的直接抛弃，但是不抛异常

        new ThreadPoolExecutor.DiscardOldestPolicy();// 抛弃队头的任务，新任务队尾进，不抛异常

        new ThreadPoolExecutor.CallerRunsPolicy();// 线程池内的线程都在忙，那就让主线程来执行新任务
    }

}
